package DFA;

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class zongHe {
    private List<Integer> list;
    private int[][] DFA1;
    private int[][] DFA2;
    private int[][] temp;
    private int midNumberofCommon;
    private ArrayList show;
    private LinkedList X;
    private LinkedList<xBuf> Xnew;
    private xBuf buf = null;
    private xBuf start = null;
    private int x1 = 1;
    private int x2 = 1;
    private TxtReadIn readIn;
    private int stateInHashmapNum;
    private List<Integer> listdfa1;//不重复DFA1的事件集合(单边+公共)
    private List<Integer> listdfa2;
    private ArrayList<Integer> mid;//公共事件子集
    private ArrayList<Integer> dfa1Fianl;
    private ArrayList<Integer> dfa2Fianl;
    public zongHe() {
    }

    public zongHe(int[][] DFA1, int[][] DFA2,TxtReadIn readIn,int stateInHashmapNum,ArrayList dfa1Fianl,ArrayList dfa2Final) {
        this.DFA1 = DFA1;
        this.DFA2 = DFA2;
        this.listdfa1 = getWayList(DFA1);
        this.listdfa2 = getWayList(DFA2);

        this.Xnew = new LinkedList<>();
        this.X = new LinkedList<xBuf>();
        this.show = new ArrayList();
        this.midNumberofCommon = getMidNumberofCommon();
        Integer[] dfa2 = getWay(DFA2);
        Integer[] dfa1 = getWay(DFA1);
        getSingleA();
        getSingleB();
        this.readIn =readIn;
        this.stateInHashmapNum=stateInHashmapNum;
        this.dfa1Fianl =dfa1Fianl;
        this.dfa2Fianl = dfa2Final;
//        this.dfa1MaxWay = dfa1[dfa1.length - 1];
//        this.dfa2MaxWay = dfa2[dfa2.length - 1];
//        if (dfa1MaxWay > dfa2MaxWay) {
//            this.DFA1 = DFA2;
//            this.DFA2 = DFA1;
//            Integer[] temp  = dfa1;
//            dfa2 = getWay(this.DFA2);
//            dfa1 = getWay(this.DFA1);
//          //  dfa1 = dfa2;
//           // dfa2 = temp;
//        } else {
//            //没交换
//            this.DFA1 = DFA1;
//            this.DFA2 = DFA2;
//        }
//        this.dfa1MaxWay = dfa1[dfa1.length - 1];
//        this.dfa2MaxWay = dfa2[dfa2.length - 1];
//        this.dfa1MinWay = dfa1[0];
//        this.dfa2MinWay = dfa2[0];
////        this.dfa1MaxWay = getMaxWAY(this.DFA1);
////        this.dfa2MaxWay = getMaxWAY(this.DFA2);
////        this.dfa1MinWay = this.DFA1[0][1];
////        this.dfa2MinWay = this.DFA2[0][1];
//        this.show = new ArrayList();
//        this.Xnew = new ArrayList();
//        this.X = new LinkedList();
//        this.midNumberofCommon = getMidNumberofCommon();
//        this.dfa2NumberofSingle = getDfa2NumberofSingle();
//        this.dfa1NumberofSingle = setDFA1singleEvents();
        this.intialize();
    }

    public void getSingleA() {
        for (int i = 0; i < mid.size(); i++) {
            listdfa1.remove(mid.get(i));
        }
    }

    public void getSingleB() {
        for (int i = 0; i < mid.size(); i++) {
            listdfa2.remove(mid.get(i));
        }
    }
    public List getWayList(int[][] dfa) {
        List<Integer> listdfa = new ArrayList<>();
        for (int i = 0; i < dfa.length; i++) {
            if (!listdfa.contains(dfa[i][1]))
                listdfa.add(dfa[i][1]);
        }
//        Integer[] array = listdfa.toArray(new Integer[listdfa.size()]);
//        Arrays.sort(array);
        return listdfa;
    }
    public Integer[] getWay(int[][] dfa) {
        list = new ArrayList<>();
        for (int i = 0; i < dfa.length; i++) {
            if (!list.contains(dfa[i][1]))
                list.add(dfa[i][1]);
        }
        Integer[] array = list.toArray(new Integer[list.size()]);//能正确        return ;
        Arrays.sort(array);
        return array;
    }

    /*
          写一个方法直接自己判断dfa的事件数
       */
//    private int setDFA1singleEvents() {
//        int dfa1Number = dfa1MaxWay - dfa1MinWay + 1;
//        return dfa1NumberofSingle = dfa1Number - midNumberofCommon;
//    }
//
//    private int getDfa2NumberofSingle() {
//        return dfa2NumberofSingle = dfa2MaxWay - dfa2MinWay + 1 - midNumberofCommon;
//    }

    //    int maxNum = dfa[0][1];
//        for (int i = 1; i < dfa.length; i++) {
//        if (maxNum < dfa[i][1]) {
//            maxNum =  dfa[i][1];
//        }
//    }
//        return maxNum;
//    private int getMaxWAY(int dfa[][]) {
//        if (dfa == null || dfa.length == 0) {
//            return 0;
//        }
//        return dfa[dfa.length - 1][1];
//    }
    private int getMidNumberofCommon() {
        int count = 0;
        mid = new ArrayList<>();
        Integer[] dfa2 = listdfa2.toArray(new Integer[listdfa2.size()]);
        for (int i = 0; i < dfa2.length; i++) {
            if (listdfa1.contains(dfa2[i])) {
                count++;
                mid.add(dfa2[i]);
            }
        }
        //相等
        return count;
    }
    public void intialize() {
        xBuf x0 = new xBuf(DFA1[0][0], DFA2[0][0]);
        //添加展示集合
        ArrayList<showState> show = new ArrayList();
        Xnew.add(x0);
        X.add(x0);

    }

    public returnPOJO finalZonghe() {
        while (Xnew != null && Xnew.size() > 0) {
            //判断abc'三个字符
            for (int i = 0; i < X.size(); i++) {
                start = (xBuf) X.get(i);
                buf = (xBuf) X.get(i);
                //得到当前状态的集合的小集合状态

                x1 = buf.getX1();
                x2 = buf.getX2();

               // if(dfa1Fianl.contains(x1) && dfa2Fianl.contains(x2))buf.setInitialized();
                for (int j = 0; j < listdfa1.size(); j++) {
                    singleDFA1(x1, x2, listdfa1.get(j),start);
                }
                //遍历DFA2的单边事件
                for (int j = 0; j < listdfa2.size(); j++) {
                    singleDFA2(x1, x2, listdfa2.get(j),start);
                }
                for (int j = 0; j < mid.size(); j++) {
                    bothActicve(x1, x2, mid.get(j),start);
                }
                //输入单边字符数，循环控制，for  的执行次数就是字符个数，for的每个i有一个
                Xnew.remove(0);
                //每回减去一个Xnew
                if (Xnew.size() == 0) {
                    jiexiUtils jiexiUtils = new jiexiUtils();
                    return jiexiUtils.arrErweiGet(show, 3, readIn, stateInHashmapNum,dfa1Fianl,dfa2Fianl);
                }

            }
        }
        return null;
    }
    private void bothActicve(int x1, int x2, Integer way,xBuf start) {

        for (int j = 0; j < DFA1.length; j++) {
            if (DFA1[j][0] != x1)//找对应的状态
                continue;
            if (DFA1[j][1] != way)//找对应的字符
                continue;
            for (int k = 0; k < DFA2.length; k++) {
                if (DFA2[k][0] != x2)//找对应的状态
                    continue;
                if (DFA2[k][1] != way)//找对应的字符
                    continue;
                xBuf Xmember = new xBuf(DFA1[j][2], DFA2[k][2]);
                showState state = new showState(start, way, Xmember);
                state.setEndString();
                state.setStartString();
                show.add(state);
                if (Xmember.isPossessState(DFA1[j][2], DFA2[k][2], Xmember, X)) {
                    Xnew.add(Xmember);
                }
                break;
            }
            break;
        }
    }
    public void singleDFA2 ( int x1, int x2, Integer way,xBuf start){
        for (int i = 0; i < DFA2.length; i++) {
            if (DFA2[i][0] != x2) continue;//排除状态不等于x2的
            if (DFA2[i][1] != way) continue;
            xBuf Xmember = new xBuf(x1, DFA2[i][2]);
            showState state = new showState(start, way, Xmember);
            state.setEndString();
            state.setStartString();
            show.add(state);
            if (Xmember.isPossessState(x1, DFA2[i][2], Xmember, X)) {
                Xnew.add(Xmember);
            }
            break;
        }
    }
    public void singleDFA1 ( int x1, int x2, int way,xBuf start){
        for (int i = 0; i < DFA1.length; i++) {
            if (DFA1[i][0] != x1) continue;//排除状态不等于x1的
            if (DFA1[i][1] != way) continue;
            xBuf Xmember = new xBuf(DFA1[i][2], x2);
            showState state = new showState(start, way, Xmember);
            state.setEndString();
            state.setStartString();
            show.add(state);
            if (Xmember.isPossessState(DFA1[i][2], x2, Xmember, X)) {
                Xnew.add(Xmember);
            }
            break;
        }
    }
//
//    public static void multiply(int dfa1NumberofSingle,
//                                int midNumberofCommon,
//                                int dfa2NumberofSingle,
//                                int[][] DFA1, int[][] DFA2, int x1, int x2,
//                                ArrayList show, xBuf start, LinkedList X, ArrayList Xnew, int dfa1MinWay,int dfa2MinWay) {
//        for (int j = dfa1MinWay; j < dfa1MinWay + dfa1NumberofSingle; j++) {
//            //DFA1单边事件  查询
//            singleA(DFA1, x1, x2, j, X, start, show, Xnew);
//            //int [][]DFA,int x1,int x2,int a,ArrayList X,xBuf start,ArrayList show,ArrayList Xnew
//        }
//        publicEvents(dfa1NumberofSingle, DFA1, DFA2, x1, x2, midNumberofCommon, show, start, X, Xnew);
////        for (int j = midNumberofCommon + dfa1NumberofSingle + 1; j < midNumberofCommon + dfa2NumberofSingle + dfa1NumberofSingle + 1; j++) {
////            zongHe.singleB(DFA2, x1, x2, j, X, start, show, Xnew);
////        }
//        for (int j = midNumberofCommon + dfa2MinWay ; j < midNumberofCommon + dfa2NumberofSingle + dfa2MinWay ; j++) {
//            zongHe.singleB(DFA2, x1, x2, j, X, start, show, Xnew);
//        }
//    }
//
//    public static int check(xBuf end, LinkedList X) {
//        Integer endX1 = end.getX1();
//        Integer endX2 = end.getX2();
//        for (int i = 0; i < X.size(); i++) {
//            xBuf o = (xBuf) X.get(i);
//            Integer x1 = o.getX1();
//            Integer x2 = o.getX2();
//            if (x1 == endX1 && x2 == endX2)
//                return o.getID();
//        }
//        return 0;
//    }
//
//    public static void publicEvents(int dfa1NumberofSingle,
//                                    int[][] DFA1, int[][] DFA2, int x1, int x2, int b,
//                                    ArrayList show, xBuf start, LinkedList X, ArrayList Xnew) {
//        for (int i = dfa1NumberofSingle + 1; i < b + dfa1NumberofSingle + 1; i++) {
//            for (int j = 0; j < DFA1.length; j++) {
//                if (DFA1[j][0] != x1)//找对应的状态
//                    continue;
//                if (DFA1[j][1] != i)//找对应的字符
//                    continue;
//                for (int k = 0; k < DFA2.length; k++) {
//                    if (DFA2[k][0] != x2)//找对应的状态
//                        continue;
//                    if (DFA2[k][1] != i)//找对应的字符
//                        continue;
//                    xBuf Xmember = new xBuf(DFA1[j][2], DFA2[k][2]);
//                    showState state = new showState(start, i, Xmember);
//                    state.setEndString();
//                    state.setStartString();
//                    show.add(state);
//                    if (Xmember.isPossessState(DFA1[j][2], DFA2[k][2], Xmember, X)) {
//                        Xnew.add(Xmember);
//                    }
//                    break;
//                }
//                break;
//            }
//        }
//
//    }
//
//    public static void singleA(int[][] DFA, int x1, int x2, int a, LinkedList X, xBuf start, ArrayList show, ArrayList Xnew) {
//        for (int j = 0; j < DFA.length; j++) {
//            if (DFA[j][0] != x1)//找对应的状态   改
//                continue;
//            if (DFA[j][1] != a)//找对应的字符
//                continue;
//            //将第二状态存储      改
//            xBuf Xmember = new xBuf(DFA[j][2], x2);
//            //添加至展示集合
//            showState state = new showState(start, a, Xmember);
//            state.setEndString();
//            state.setStartString();
//            show.add(state);
//            //判断Xmember在X集合中是否存在，若存在加入X和Xnew中   改
//            if (Xmember.isPossessState(DFA[j][2], x2, Xmember, X)) {
//                Xnew.add(Xmember);
//            }
//            break;
//        }
//    }
//
//    public static void singleB(int[][] DFA, int x1, int x2, int a, LinkedList X, xBuf start, ArrayList show, ArrayList Xnew) {
//        for (int j = 0; j < DFA.length; j++) {
//            if (DFA[j][0] != x2)//找对应的状态   改
//                continue;
//            if (DFA[j][1] != a)//找对应的字符
//                continue;
//            //将第二状态存储      改
//            xBuf Xmember = new xBuf(x1, DFA[j][2]);
//            //添加至展示集合
//            showState state = new showState(start, a, Xmember);
//            state.setEndString();
//            state.setStartString();
//            show.add(state);
//            //判断Xmember在X集合中是否存在，若存在加入X和Xnew中   改
//            if (Xmember.isPossessState(x1, DFA[j][2], Xmember, X)) {
//                Xnew.add(Xmember);
//            }
//            break;
//        }
//    }
}
